package com.yanqu.road.entity.activity.daomu.pvp.helper;

import com.yanqu.road.entity.activity.daomu.pvp.Coordinate;

import java.util.List;

/**
 * 碰撞辅助类
 */
public class CollisionHelper {

    private static boolean isSeparatingAxis(Coordinate p1, Coordinate p2, List<Coordinate> points1, List<Coordinate> points2) {
        double dx = p2.getX() - p1.getX();
        double dy = p2.getY() - p1.getY();

        Coordinate axis = new Coordinate(-dy, dx); // 垂直于边的向量
        double minA = Double.MAX_VALUE;
        double maxA = Double.MIN_VALUE;
        for (Coordinate p : points1) {
            double projection = projection(p, axis);
            minA = Math.min(minA, projection);
            maxA = Math.max(maxA, projection);
        }

        double minB = Double.MAX_VALUE;
        double maxB = Double.MIN_VALUE;
        for (Coordinate p : points2) {
            double projection = projection(p, axis);
            minB = Math.min(minB, projection);
            maxB = Math.max(maxB, projection);
        }

        if (maxA < minB || maxB < minA) {
            return true; // 找到了分离轴
        } else {
            return false;
        }
    }

    private static double projection(Coordinate a, Coordinate b) {
        return dotProduct(a, b) / (Math.sqrt(b.getX() * b.getX() + b.getY() * b.getY()));
    }

    private static double dotProduct(Coordinate a, Coordinate b) {
        return a.getX() * b.getX() + a.getY() * b.getY();
    }


    /**
     * 矩形碰撞
     */
    public static boolean intersectsWithRectangle(List<Coordinate> points1, List<Coordinate> points2) {
        for (int i = 0; i < points1.size(); i++) {
            Coordinate p1 = points1.get(i);
            Coordinate p2 = points1.get((i + 1) % points1.size());

            if (isSeparatingAxis(p1, p2, points1, points2)) {
                return false;
            }
        }

        for (int i = 0; i < points2.size(); i++) {
            Coordinate p1 = points2.get(i);
            Coordinate p2 = points2.get((i + 1) % points2.size());

            if (isSeparatingAxis(p1, p2, points1, points2)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 矩形与圆形的碰撞
     *
     * @param points
     * @param circleCenter
     * @param radius
     * @return
     */
    public static boolean intersectsWithCircle(List<Coordinate> points, Coordinate circleCenter, double radius) {
        // 寻找最近的矩形顶点
        double minDistance = Double.MAX_VALUE;
        for (Coordinate myPoint : points) {
            minDistance = Math.min(minDistance, distanceSquared(circleCenter, myPoint));
        }

        // 检查最近的顶点是否在圆内
        if (minDistance <= radius * radius) {
            return true;
        }

        // 检查每个边是否与圆相交
        for (int i = 0; i < points.size(); i++) {
            Coordinate p1 = points.get(i);
            Coordinate p2 = points.get((i + 1) % points.size());

            if (lineIntersectsCircle(p1, p2, circleCenter, radius)) {
                return true;
            }
        }

        return false;
    }

    private static double distanceSquared(Coordinate p1, Coordinate p2) {
        double dx = p1.getX() - p2.getX();
        double dy = p1.getY() - p2.getY();
        return dx * dx + dy * dy;
    }

    private static boolean lineIntersectsCircle(Coordinate p1, Coordinate p2, Coordinate circleCenter, double radius) {
        double lineLengthSquared = distanceSquared(p1, p2);

        double t = ((circleCenter.getX() - p1.getX()) * (p2.getX() - p1.getX()) + (circleCenter.getY() - p1.getY()) * (p2.getY() - p1.getY())) / lineLengthSquared;

        if (t < 0.0 || t > 1.0) {
            return false; // 线段与圆的最近点不在线段上
        }

        Coordinate closestPointOnLine = new Coordinate(p1.getX() + t * (p2.getX() - p1.getX()), p1.getY() + t * (p2.getY() - p1.getY()));

        return distanceSquared(closestPointOnLine, circleCenter) <= radius * radius;
    }


}
